package com.gzsxy.esjy.redis.extend.impl;

import com.gzsxy.esjy.common.base.exception.impl.CustomAssert;
import com.gzsxy.esjy.redis.extend.RedisLock;

import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author xiaolong
 * @version 1.0
 * @description: 基础分布式锁
 * @date 2021/12/28 14:30
 */
public abstract class BaseDistributeLock implements RedisLock {
    public BaseDistributeLock(){
    }

    @Override
    public Object excute(Function<Lock,Object> excute, Lock lock){
        Object result = null;
        boolean flag = false;

        try {
            //获取锁成功后
            if (this.tryLock(lock.getKey(),lock.getGroup(),lock.getMaxWaitTime(),lock.getTimeInterval())){
                flag = true;
                //执行函数中的内容
                result = excute.apply(lock);
            } else {
                //抛出异常
                CustomAssert.notTrue(false,lock.getFailMsg(),504);
            }
        } finally {
            //执行成功后释放锁
            if (flag){
                this.unLock(lock.getKey(),lock.getGroup());
            }
        }
        return result;
    }


    @Override
    public void excute(Lock lock, Consumer<Lock> excute){
        this.excute((e) ->{
            excute.accept(lock);
            return null;
        },lock);
    }


    @Override
    public void excute(Lock[] locks, Consumer<Lock[]> excute){
        this.excute((Function) ((e) ->{
            excute.accept(locks);
            return null;
        }), (Lock[]) locks);
    }


}
